% Prepare environment
clc
clear
close all
addpath(genpath('../csrd'));

% Generate audio signal
source = blocks.physical.message.Audio(scale = 5);
x = source(10000, 0);

% Modulate x using NBFM
ModulatorConfig.FrequencyDeviation = 2e3;
ModulatorConfig.InitPhase = 0;
baseBandSignal = blocks.physical.modulate.analog.FM.NBFM(ModulatorConfig = ModulatorConfig, ...
    NumTransmitAntennas = 1, ...
    SampleRate = x.SymbolRate);

x1 = baseBandSignal(x);

% demod FM and verify
upConv = dsp.DigitalUpConverter( ...
    'InterpolationFactor', 5, ...
    'SampleRate', x1.SampleRate, ...
    'Bandwidth', max(abs(x1.BandWidth)) * 2, ...
    'StopbandAttenuation', 55, ...
    'PassbandRipple', 0.2, ...
    'CenterFrequency', 40e3);

dwnConv = dsp.DigitalDownConverter( ...
    'DecimationFactor', 5, ...
    'SampleRate', x1.SampleRate * 5, ...
    'Bandwidth', max(abs(x1.BandWidth)) * 2, ...
    'StopbandAttenuation', 55, ...
    'PassbandRipple', 0.2, ...
    'CenterFrequency', 40e3);

a1 = x1.data;
b1 = upConv(a1);
scope1 = spectrumAnalyzer(SampleRate = x1.SampleRate * 5, AveragingMethod = "exponential", RBWSource = "auto", SpectrumUnits = "dBW");
scope1(b1);

c1 = dwnConv(b1);
scope2 = spectrumAnalyzer(SampleRate = x1.SampleRate, AveragingMethod = "exponential", RBWSource = "auto", SpectrumUnits = "dBW");
scope2(c1);

fmDeMod = comm.FMDemodulator("SampleRate", x1.SampleRate, "FrequencyDeviation", x1.ModulatorConfig.FrequencyDeviation);

d1 = lowpass(c1, max(abs(x1.BandWidth)), x1.SampleRate, ...
    ImpulseResponse = "fir", ...
    Steepness = 0.99999, StopbandAttenuation = 200);
e1 = fmDeMod(d1);

% Modulate x using WBFM
ModulatorConfig.FrequencyDeviation = 5e4;
ModulatorConfig.InitPhase = 0;
baseBandSignal = blocks.physical.modulate.analog.FM.WBFM(ModulatorConfig = ModulatorConfig, ...
    NumTransmitAntennas = 1, ...
    SampleRate = x.SymbolRate);

x2 = baseBandSignal(x);

% demod FM and verify
upConv = dsp.DigitalUpConverter( ...
    'InterpolationFactor', 5, ...
    'SampleRate', x2.SampleRate, ...
    'Bandwidth', max(abs(x2.BandWidth)) * 2, ...
    'StopbandAttenuation', 55, ...
    'PassbandRipple', 0.2, ...
    'CenterFrequency', 40e3);

dwnConv = dsp.DigitalDownConverter( ...
    'DecimationFactor', 5, ...
    'SampleRate', x2.SampleRate * 5, ...
    'Bandwidth', max(abs(x2.BandWidth)) * 2, ...
    'StopbandAttenuation', 55, ...
    'PassbandRipple', 0.2, ...
    'CenterFrequency', 40e3);

a2 = x2.data;
b2 = upConv(a2);
scope1 = spectrumAnalyzer(SampleRate = x2.SampleRate * 5, AveragingMethod = "exponential", RBWSource = "auto", SpectrumUnits = "dBW");
scope1(b2);

c2 = dwnConv(b2);
scope2 = spectrumAnalyzer(SampleRate = x2.SampleRate, AveragingMethod = "exponential", RBWSource = "auto", SpectrumUnits = "dBW");
scope2(c2);

fmDeMod = comm.FMDemodulator("SampleRate", x2.SampleRate, "FrequencyDeviation", x2.ModulatorConfig.FrequencyDeviation);
d2 = lowpass(c2, max(abs(x2.BandWidth)), x2.SampleRate, ...
    ImpulseResponse = "fir", ...
    Steepness = 0.99999, StopbandAttenuation = 200);
e2 = fmDeMod(d2);
src = dsp.SampleRateConverter( ...
    'Bandwidth', max(abs(x2.BandWidth)) * 2, ...
    'InputSampleRate', x2.SampleRate, ...
    'OutputSampleRate', x2.SampleRate / 10, ...
    'StopbandAttenuation', 100);
e2 = src(e2);
